'use strict';
// node.js 文件操作对象
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
// 故名思意 异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
// 管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
const Pump = require('mz-modules/pump');
const upload = require('../../utils/cos');
const Controller = require('egg').Controller;
class PhotoController extends Controller {
  async create() {
    const ctx = this.ctx;
    this.md5 = crypto.createHash('md5');
    // egg-multipart 已经帮我们处理文件二进制对象
    // node.js 和 php 的上传唯一的不同就是 ，php 是转移一个 临时文件
    // node.js 和 其他语言（java c#） 一样操作文件流
    const stream = await ctx.getFileStream();
    // 新建一个文件名
    const filename =
      new Date().getTime() + path.extname(stream.filename).toLocaleLowerCase();
    // 文件生成绝对路径
    // 当然这里这样市不行的，因为你还要判断一下是否存在文件路径
    const target = path.join(this.config.baseDir, 'app/public/uploads', filename);
    // 生成一个文件写入 文件流
    const writeStream = fs.createWriteStream(target);
    try {
      // 异步把文件流 写入
      await awaitWriteStream(stream.pipe(writeStream));
    } catch (err) {
      // 如果出现错误，关闭管道
      await sendToWormhole(stream);
      throw err;
    }
    // 文件响应
    ctx.body = {
      msg: '/public/uploads/' + filename,
      status: 200,
    };
  }
  async updateMultiple() {
    // autoFields: true 表示除了文件的其它字段
    const parts = this.ctx.multipart({autoFields: true});
    const files = [];
    let stream;
    // 循环获取数据流
    while ((stream = await parts()) != null) {
      if (!stream.filename) {
        // 多文件上传时，只能break,不能return
        break;
      }

      // 文件表单的name
      // 上传的目录，注意upload目录要存在，实际项目中以云服务器地址为准，入库要替换地址符号
      const filename = new Date().getTime() + path.extname(stream.filename);
      // 文件生成绝对路径
      // 当然这里这样市不行的，因为你还要判断一下是否存在文件路径
      const target = path.join(this.config.baseDir, 'app/public/uploads', filename);

      const writeStream = fs.createWriteStream(target);
      await Pump(stream, writeStream);

      files.push(target);
    }
    // 返回上传的信息
    this.ctx.body = {
      status: 200,
      // 表单上传的文件
      files,
      // 表单的其它数据，注意放到循环后面，否则拿不到对应的字段
      fields: parts.field,
    };
  }

  /**
   *
   * @api {POST} /api/upload/base64 上传base64图片
   * @apiName 上传base64图片
   * @apiGroup 图片
   * @apiVersion  1.0.0
   *
   *
   * @apiParam  {Base64} file base64格式的图片
   *
   * @apiSuccess (200) {type} name description
   *
   * @apiParamExample  {type} Request-Example:
   * {
   *     file : "/9j/4AAQSkZJRgABAQAASABIAAD/2wBDAAcFBQYFBAcGBgYIBwcICxILCwoKCxYPEA0SGhYb"
   * }
   *
   *
   * @apiSuccessExample {type} Success-Response:
      {
        msg: '成功操作',
        result: {
          url: 'http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1684416696213.png',
        },
      };
   *
   *
   */
  async uploadBase64() {
    const {ctx} = this;
    const {file} = ctx.request.body;

    const buffer = Buffer.from(file, 'base64');
    const filename = new Date().getTime() + '.png';
    const result = await upload(filename, buffer);
    ctx.body = ctx.response.success({url: result});
  }
}

module.exports = PhotoController;
